home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1997 August / Walnut Creek CDROM.7z / VOL_400 / 453_01 / EXAMPLES / DUMP / DUMP.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-27  |  6.9 KB  |  308 lines

  1. //    dump.cpp  -  datafile dump utility sample code  -  1.2
  2. //
  3. //    This is a part of the MetaKit library.
  4. //    Copyright (c) 1996 Meta Four Software.
  5. //    All rights reserved.
  6. /////////////////////////////////////////////////////////////////////////////
  7. //
  8. //    This command-line utility displays different aspects of a datafile
  9. //    created with the MetaKit library: field structure (-f), low-level
  10. //    table structure (-s), low-level table contents dump (-d), or a
  11. //    normal dump of the entire view contents (default).
  12. //
  13. /////////////////////////////////////////////////////////////////////////////
  14.  
  15. #include "m4kit.h"
  16. #include "k4field.h"
  17. #include "k4table.h"
  18.  
  19. /////////////////////////////////////////////////////////////////////////////
  20. // Recursively display the field structure, table contents is not used here.
  21.  
  22. static void FieldDisplay(c4_Field& f_, int l_ =0)
  23. {
  24.     printf("%*s FIELD %s  off %d, width %d, depth %d : %s\n",
  25.                     l_, "",
  26.                     f_.IsRepeating() ? "[*] " : "",
  27.                     f_.Offset(), f_.Width(), f_.Depth(),
  28.                     (const char*) f_.Tag());
  29.  
  30.     int nc = f_.NumSubColumns();
  31.     if (nc > 0)
  32.     {
  33.         printf("%*s   columns:", l_, "");
  34.         for (int i = 0; i < nc; ++i)
  35.             printf(" %d.%s", i, (const char*) f_.SubColumn(i).Name());
  36.         printf("\n");
  37.     }
  38.  
  39.     int nf = f_.NumSubFields();
  40.     if (nf > 0)
  41.     {
  42.         printf("%*s    fields:", l_, "");
  43.         for (int i = 0; i < nf; ++i)
  44.             printf(" %d.%s", i, (const char*) f_.SubField(i).Name());
  45.         printf("\n");
  46.  
  47.         for (int j = 0; j < nf; ++j)
  48.                 // skip first field in root to avoid infinite recursion
  49.             if (l_ > 0 || j > 0)
  50.                 FieldDisplay(f_.SubField(j), l_ + 2);
  51.     }
  52. }
  53.  
  54. /////////////////////////////////////////////////////////////////////////////
  55. // Recursively display the raw table structure (optionally also contents).
  56. // This code does not use views, and attempts to continue after all errors.
  57.  
  58. static bool TableDisplay(c4_Table& t_, bool full_, int l_ =0)
  59. {
  60.     int errors = 0;
  61.  
  62.     int nr = t_.NumRows();
  63.     int nc = t_.NumColumns();
  64.  
  65.     printf("%*s TABLE %5d rows, %d cols\n", l_, "", nr, nc);
  66.  
  67.     for (int i = 0; i < nc; ++i)
  68.     {
  69.         c4_Field& f = t_.Field(i);
  70.  
  71.         if (f.IsRepeating())
  72.         {
  73.             for (int k = 0; k < nr; ++k)
  74.             {
  75.                 printf("%*s %4d: subtable [%d] %s\n", l_, "", i, k,
  76.                         (const char*) f.Name());
  77.  
  78.                     // skip first field in root to avoid infinite recursion
  79.                 if (l_ > 0 || i > 0)
  80.                     try
  81.                     {
  82.                         if (!TableDisplay(t_.SubTable(i, k), full_, l_ + 2))
  83.                             ++errors;
  84.                     }
  85.                     catch (...)
  86.                     {
  87.                         printf("*** Error in subtable (%s[%d].%s) ***\n",
  88.                                     (const char*) t_.Definition().Tag(),
  89.                                         k, (const char*) f.Name());
  90.                         ++errors;
  91.                     }
  92.  
  93.                 if (errors >= 5)
  94.                 {
  95.                     printf("*** Too many errors, bailing out ***\n");
  96.                     break;
  97.                 }
  98.             }
  99.         }
  100.         else
  101.         {
  102.             c4_Column& c = t_.Column(i);
  103.             printf("%*s %4d:%5u @ %-5lu %s", l_, "", i,
  104.                     c.Size(), c.Position(), (const char*) f.Name());
  105.  
  106.             if (full_)
  107.             {
  108.                 const uchar* data = t_.LoadColumn(i);
  109.  
  110.                     // produces a readable hex/ascii dump of column c
  111.                 for (ulong j = 0; j < c.Size(); j += 16)
  112.                 {
  113.                     printf("\n %22lu: ", j);
  114.  
  115.                     for (int k = 0; k < 16; ++k)
  116.                     {
  117.                         if (k % 4 == 0)
  118.                             printf(" ");
  119.  
  120.                         if (j + k < c.Size())
  121.                             printf("%02X", data[j+k]);
  122.                         else
  123.                             printf("  ");
  124.                     }
  125.  
  126.                     printf("  ");
  127.  
  128.                     for (int l = 0; l < 16; ++l)
  129.                     {
  130.                         int ch = ' ';
  131.                         if (j + l < c.Size())
  132.                         {
  133.                             ch = data[j+l] & 0x7F;
  134.                             if (ch < ' ' || ch > '~')
  135.                                 ch = ' ';
  136.                         }
  137.  
  138.                         printf("%c", ch);
  139.                     }
  140.                 }
  141.             }
  142.  
  143.             printf("\n");
  144.         }
  145.     }
  146.  
  147.     return errors == 0;
  148. }
  149.  
  150. /////////////////////////////////////////////////////////////////////////////
  151. // Recursively display the entire view contents. The results shown do not
  152. // depend on file layout (free space, file positions, flat vs. on-demand).
  153.  
  154. static void ViewDisplay(const c4_View& v_, int l_ =0)
  155. {
  156.     CString types;
  157.     bool hasData = false, hasSubs = false;
  158.  
  159.         // display header info and collect all data types
  160.     printf("%*s VIEW %5d rows =", l_, "", v_.GetSize());
  161.     for (int n = 0; n < v_.NumProperties(); ++n)
  162.     {
  163.         c4_Property prop = v_.NthProperty(n);
  164.         char t = prop.Type();
  165.  
  166.         printf(" %s:%c", (const char*) prop.Name(), t);
  167.         
  168.         types += t;
  169.     
  170.         if (t == 'V')
  171.             hasSubs = true;
  172.         else
  173.             hasData = true;
  174.     }
  175.     printf("\n");
  176.  
  177.     for (int j = 0; j < v_.GetSize(); ++j)
  178.     {
  179.         if (hasData)    // data properties are all shown on the same line
  180.         {
  181.             printf("%*s %4d:", l_, "", j);
  182.             c4_RowRef r = v_[j];
  183.  
  184.             for (int k = 0; k < types.GetLength(); ++k)
  185.             {
  186.                 c4_Property p = v_.NthProperty(k);
  187.  
  188.                 switch (types[k])
  189.                 {
  190.                 case 'I':
  191.                     printf(" %d", (int) ((c4_IntProp&) p) (r));
  192.                     break;
  193.  
  194.                 case 'F':
  195.                     printf(" %g", (double) ((c4_FloatProp&) p) (r));
  196.                     break;
  197.  
  198.                 case 'S':
  199.                     printf(" '%s'", (const char*) (c4_String)
  200.                                         ((c4_StringProp&) p) (r));
  201.                     break;
  202.  
  203.                 default:
  204.                     if (types[k] != 'V')
  205.                         printf(" (%c?)", types[k]);
  206.                 }
  207.             }
  208.  
  209.             printf("\n");
  210.         }
  211.  
  212.         if (hasSubs)    // subviews are then shown, each as a separate block
  213.         {
  214.             for (int k = 0; k < types.GetLength(); ++k)
  215.             {
  216.                 if (types[k] == 'V')
  217.                 {
  218.                     c4_Property prop = v_.NthProperty(k);
  219.  
  220.                     printf("%*s %4d: subview '%s'\n", l_, "", j,
  221.                             (const char*) prop.Name());
  222.  
  223.                     if (l_ > 0 || k > 0)
  224.                     {
  225.                         c4_ViewProp& vp = (c4_ViewProp&) prop;
  226.  
  227.                         ViewDisplay(vp (v_[j]), l_ + 2);
  228.                     }
  229.                 }
  230.             }
  231.         }
  232.     }
  233. }
  234.  
  235. /////////////////////////////////////////////////////////////////////////////
  236.  
  237. int main(int argc, char** argv)
  238. {
  239.     bool sFlag = false, dFlag = false, fFlag = false, wFlag = false;
  240.  
  241.     while (argc > 1 && (argv[1][0] == '-' || argv[1][0] == '/'))
  242.     {
  243.         --argc;
  244.         switch ((*++argv)[1])
  245.         {
  246.         case 's': case 'S':        sFlag = true; break;
  247.         case 'd': case 'D':        dFlag = true; break;
  248.         case 'f': case 'F':        fFlag = true; break;
  249.         case 'w': case 'W':        wFlag = true; break;
  250.         }
  251.     }
  252.  
  253.     const char* msg = 0;
  254.     
  255.     if (argc != 2)
  256.         fprintf(stderr, "Usage: DUMP [-s|-d|-f|-w] file\n");
  257.     else
  258.         try
  259.         {
  260.             msg = "could not open data file";
  261.  
  262.             CFile data (argv[1], CFile::modeRead);
  263.  
  264.             msg = "file may be damaged";
  265.  
  266.             c4_Storage store (&data);
  267.             c4_View base = store.Contents().Container();
  268.  
  269.             printf("%s: %d properties\n  %s\n\n",
  270.                                     argv[1], base.NumProperties(),
  271.                                     (const char*) store.Description());
  272.  
  273.                 
  274.             if (sFlag || dFlag || fFlag)
  275.             {
  276.                 c4_Table& root = store.RootTable();
  277.                 c4_Field& field = root.Definition();
  278.  
  279.                 if (fFlag)
  280.                 {
  281.                     FieldDisplay(field);
  282.                     msg = 0;
  283.                 }
  284.                 else if (TableDisplay(root, dFlag))
  285.                     msg = 0;
  286.             }
  287.             else
  288.             {
  289.                 ViewDisplay(base);
  290.  
  291.                 msg = 0;
  292.             }
  293.         }
  294.         catch (...)
  295.         {
  296.         }
  297.     
  298.     if (msg)
  299.         fprintf(stderr, "Abnormal termination, %s\n", msg);
  300.  
  301.     if (wFlag)
  302.         getchar();
  303.  
  304.     return msg ? 1 : 0;
  305. }
  306.  
  307. /////////////////////////////////////////////////////////////////////////////
  308.